package com.yuw.ProducerAndConsumer;

/**
 * 仓库类【以栈的方式实现】
 * 
 * @author Administrator
 *
 */
public class WarehouseStack {
	// 属性
	// 仓库的容量
	private int len;
	// 仓库采用数组存储
	private Product[] warehouse;

	// 栈顶位置【栈顶为最上元素的上一个位置】【第一个空余位置】
	private int index;

	// 行为
	public WarehouseStack(int len) {
		super();
		this.len = len;
		// 初始化仓库
		warehouse = new Product[this.len];
		// 初始化栈顶位置
		index = 0;
	}

	/**
	 * 进栈操作
	 * 
	 * @param pro
	 *            被进栈的产品
	 */
	public synchronized void push(Product pro) {

		if (index >= len) {
			// 仓库已满，生产者需要等待消费者消费
			// 生产者进入等待队列
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// 将产品放入栈顶位置
		warehouse[index] = pro;
		// 栈顶位置向上移动一个位置
		index++;
		// 输出信息
		System.out.println("入库操作：" + pro.getProductName());

		// 入库操作完成以后，说明仓库中有产品了，可以消费了，需要将之前等待生产者生产产品的消费者唤醒
		this.notifyAll();
	}

	/**
	 * 出栈操作
	 * 
	 * @return 出栈的产品对象
	 */
	public synchronized Product pop() {

		if (index <= 0) {
			// 仓库为空，消费者需要等待生产者生产产品
			// 消费者进入等待队列
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// 出栈的产品
		Product pro = null;
		// 栈顶位置向下移动一个位置
		index--;
		// 出栈
		pro = warehouse[index];
		// 出栈之后栈元素为null
		warehouse[index] = null;
		// 输出信息
		System.out.println("出库操作：" + pro.getProductName());

		// 出库操作完成以后，说明仓库中有空余空间了，生产者可以生产了，需要将之前等待消费者消费产品的生产者唤醒
		this.notifyAll();

		return pro;

	}
}
